package com.cll.pmis.common.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;

/**
 * @author chenliangliang
 * @date 2018/6/19
 */
public class CryptoUtil {


    private static final String HEX_STRING = "0123456789ABCDEF";
    private static final Integer SALT_LENGTH = 32;
    private static SecureRandom random = new SecureRandom();


    public static byte[] hexStr2Byte(String hex) {
        int len = hex.length() >>> 1;
        byte[] res = new byte[len];
        char[] chars = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i << 1;
            res[i] = (byte) (HEX_STRING.indexOf(chars[pos]) << 4 | HEX_STRING.indexOf(chars[pos + 1]));
        }
        return res;
    }

    public static String byte2HexStr(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte aByte : bytes) {
            String hex = Integer.toHexString(aByte & 0xFF);
            if (hex.length() == 1) {
                hex += "0";
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }


    public static byte[] encode(String msg, int saltLength) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        byte[] salt = new byte[saltLength];
        random.nextBytes(salt);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(salt);
        md5.update(msg.getBytes("UTF-8"));

        byte[] digest = md5.digest();

        byte[] res = new byte[digest.length + saltLength];
        System.arraycopy(salt, 0, res, 0, saltLength);
        System.arraycopy(digest, 0, res, saltLength, digest.length);

        return res;
    }

    public static byte[] encode(String msg) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        return encode(msg, SALT_LENGTH);
    }


    public static String encode2HexStr(String msg) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        return byte2HexStr(encode(msg));
    }


    public static boolean valid(String str, String encodedStr, int saltLength) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        return valid(str.getBytes("UTF-8"),hexStr2Byte(encodedStr),saltLength);
    }

    public static boolean valid(String str, String encodedStr) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        return valid(str.getBytes("UTF-8"),hexStr2Byte(encodedStr),SALT_LENGTH);
    }


    public static boolean valid(byte[] bytes, byte[] encodedBytes, int saltLength) throws NoSuchAlgorithmException {

        byte[] salt = new byte[saltLength];
        System.arraycopy(encodedBytes, 0, salt, 0, saltLength);

        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(salt);
        md5.update(bytes);

        byte[] digest = md5.digest();

        byte[] oldDigest = new byte[encodedBytes.length - saltLength];
        System.arraycopy(encodedBytes, saltLength, oldDigest, 0, oldDigest.length);

        return Arrays.equals(digest, oldDigest);
    }


    public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String pwd="cll123456";
        String s = encode2HexStr(pwd);
        System.out.println("加密后密码："+s);
        System.out.println(new String(hexStr2Byte(byte2HexStr(pwd.getBytes("UTF-8"))),"UTF-8"));
        System.out.println(valid(pwd,s));
    }

}
